import imghdr
import logging
import re
import traceback

from PIL.Image import Image
import base64
import mimetypes
from pathlib import Path


def image_to_base64(image_path: str) -> str:
    try:
        image_path = Path(image_path)
        file_type = imghdr.what(image_path)
        if not file_type:
            raise ValueError("无法识别图片类型")

        # 限制为常用格式
        if file_type not in ["jpeg", "png"]:
            raise ValueError(f"不支持的图片格式: {file_type}")

        mime_type = f"image/{file_type}"
        with open(image_path, "rb") as img_file:
            encoded = base64.b64encode(img_file.read()).decode("utf-8")
            return f"data:{mime_type};base64,{encoded}"
    except Exception as e:
        logging.error(traceback.format_exc())
        raise RuntimeError(f"图片转 base64 失败: {e}")


def base64_to_image(base64_str: str, output_path: str) -> str:
    """
    将 base64 字符串还原为图片
    :param base64_str: base64 字符串（带 or 不带头部）
    :param output_path: 输出文件路径（不带扩展名）
    :return: 实际保存路径（含扩展名）
    """
    try:
        # 提取 mime 类型
        match = re.match(r'data:image/(.*?);base64,(.*)', base64_str)
        if match:
            ext, data = match.groups()
        else:
            # 无头部
            ext = "png"
            data = base64_str

        image_data = base64.b64decode(data)
        real_path = f"{output_path}.{ext}"
        with open(real_path, "wb") as f:
            f.write(image_data)
        return real_path
    except Exception as e:
        raise RuntimeError(f"base64 转图片失败: {e}")


def convert_image_format(input_path: str, output_path: str, target_format: str = 'JPEG'):
    """
    将图片强制转换为目标格式
    :param input_path: 原图路径
    :param output_path: 输出路径（建议不带扩展名）
    :param target_format: 目标格式（'JPEG', 'PNG', 等）
    :return: 实际保存路径
    """
    try:
        img = Image.open(input_path).convert("RGB")
        ext_map = {'JPEG': 'jpg', 'PNG': 'png', 'WEBP': 'webp'}
        ext = ext_map.get(target_format.upper(), target_format.lower())
        real_path = f"{output_path}.{ext}"
        img.save(real_path, target_format.upper())
        return real_path
    except Exception as e:
        raise RuntimeError(f"图片格式转换失败: {e}")


def get_image_format_from_base64(base64_str: str) -> str:
    """
    根据 base64 字符串头部获取图片格式
    :param base64_str: base64 字符串
    :return: 文件扩展名（如 .jpg / .png）
    """
    match = re.match(r'data:image/(.*?);base64,', base64_str)
    if match:
        ext = match.group(1).lower()
        if ext == "jpeg":
            return ".jpg"
        return f".{ext}"
    return ".png"  # 默认
